import sys
from django.conf import settings
from django.core.management.commands import syncdb
try:
    settings.configure(DATABASE_ENGINE='sqlite3', 
                       DATABASE_NAME = ':memory:', 
                       INSTALLED_APPS = ('simcat',))
    syncdb.Command().handle_noargs(verbosity=0, interactive=False)
except:
    pass

import cStringIO
import httplib2
from django.utils import simplejson
import simcat.models as models

import utils
urlmap = {}
for collection in utils.collections_list():
    urlmap[collection._meta.object_name.lower()] = collection

class SimCatClient(object):
    baseurl = 'http://localhost:8000/simcat/api/'

    def __init__(self, baseurl='', user=None, passwd=None):
        if baseurl:
            self.baseurl = baseurl
        self.h = httplib2.Http()
        if user and passwd:
            self.h.add_credentials(user, passwd)

    def get(self, model_name, id):
        if isinstance(id, str):
            url = '%s%s/%s/' % (self.baseurl, model_name.lower(), id)
        elif isinstance(id, int):
            url = '%s%s/%d/' % (self.baseurl, model_name.lower(), id)
        else:
            return None
        resp, content = self.h.request(url)
        new_obj = urlmap[model_name]()
        new_obj.from_json(content, preserve_ids=True)
        return new_obj

    def load_instance(self, file_or_filename):
        """Loads an instance from a JSON file."""
        if isinstance(file_or_filename, basestring):
            fin = open(file_or_filename)
            new_obj = self._load_instance(fin)
            fin.close()           
        else:
            # assume it's a file
            new_obj = self._load_instance(file_or_filename)

        return new_obj

    def _load_instance(self, file_like):
        instance_dict = simplejson.load(file_like)
        new_obj = eval('models.' + instance_dict['model'])()
        new_obj.from_dict(instance_dict, preserve_ids=True)
        return new_obj

    def add(self, instance):
        url = '%s%s/' % (self.baseurl, instance._meta.object_name.lower())
        json_txt = instance.to_json()
        headers = {'Content-Type': 'application/json; charset=utf-8'}
        response, content = self.h.request(url, method="POST", 
                                           body=json_txt, headers=headers)
        if response.status == 201:
            # sync the ids
            fin = cStringIO.StringIO(content)
            instance.delete()
            instance = self.load_instance(fin)
            fin.close()
            return instance
        else:
            raise Exception('Failed to save new instance.', instance, response, content)

    def delete(self, model_name, id):
        url = '%s%s/%d/' % (self.baseurl, model_name.lower(), id)
        response, content = self.h.request(url, method="DELETE")
        print content

    def update(self, instance):
        url = '%s%s/%d/' % (self.baseurl, instance.__class__.__name__.lower(),
                             instance.id)
        headers = {'Content-Type': 'application/json; charset=utf-8 '}
        json_txt = instance.to_json()
        response, content = self.h.request(url, method="PUT", 
                                           body=json_txt, headers=headers)

def load_and_post(filename):
    s = SimCatClient()
    o = s.load_instance(filename)
    s.add(o, 'foo', 'magoo')

def get(model_name, id, baseurl='',
        user=None, passwd=None):
    s = SimCatClient(baseurl, user, passwd)
    return s.get(model_name, id)

def add(instance, baseurl='',
        user=None, passwd=None):
    s = SimCatClient(baseurl, user, passwd)
    return s.add(instance)

def update(instance, baseurl='',
           user=None, passwd=None):
    s = SimCatClient(baseurl, user, passwd)
    s.update(instance)
